package ar.edu.itba.pod.legajo48062;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import ar.edu.itba.node.Node;
import ar.edu.itba.node.NodeInformation;
import ar.edu.itba.pod.time.TimeMapper;

public class Host {
	public static long processedEventsRemoveFrequency = 60000;
	public static long electionMessagesRemoveFrequency = 60000;
	public static long coordinatorMessagesRemoveFrequency = 60000;
	public static long pullEventsFrequency = 10000;
	public static long eventOld = 30000;
	public static double gossipStopProportion = 0.1;
	public static int secondsToWaitOKs = 5;
	
	private Cluster cluster;
	private WrapperEventDispatcher localDispatcher;
	private DistributedAgentsTransfer agentsTransfer;
	private DistributedAgentsBalancer agentsBalancer;
	private DistributedEventDispatcher remoteDispatcher;
	private DistributedSimulation node;
	private DistributedStatisticReports statisticReports;
	
	public Host(NodeInformation me, TimeMapper timeMapper) {
		try{
			cluster = new Cluster(me);
			localDispatcher=new WrapperEventDispatcher(cluster);
			remoteDispatcher = new DistributedEventDispatcher(cluster, localDispatcher);
			localDispatcher.setRemoteDispatcher(remoteDispatcher);
			agentsBalancer= new DistributedAgentsBalancer(cluster);
			node = new DistributedSimulation(timeMapper, localDispatcher, agentsBalancer, cluster);
			cluster.setAgentsBalancer(agentsBalancer);
			cluster.setNode(node);
			agentsBalancer.setNode(node);
			agentsTransfer= new DistributedAgentsTransfer(node, remoteDispatcher);
			statisticReports = new DistributedStatisticReports(node);
			
			Registry registry = LocateRegistry.createRegistry(me.port());
			registry.bind(Node.CLUSTER_COMUNICATION, cluster);
			registry.bind(Node.DISTRIBUTED_EVENT_DISPATCHER, remoteDispatcher);
			registry.bind(Node.AGENTS_BALANCER, agentsBalancer);
			registry.bind(Node.AGENTS_TRANSFER, agentsTransfer);
			registry.bind(Node.STATISTIC_REPORTS, statisticReports);
		}catch (Exception e) {
			// ACA NO DEBERIA ENTRAR
		}
	}

	public Cluster getCluster() {
		return cluster;
	}

	public WrapperEventDispatcher getLocalDispatcher() {
		return localDispatcher;
	}

	public DistributedAgentsTransfer getAgentsTransfer() {
		return agentsTransfer;
	}

	public DistributedAgentsBalancer getAgentsBalancer() {
		return agentsBalancer;
	}

	public DistributedSimulation getNode() {
		return node;
	}

	public DistributedStatisticReports getStatisticReports() {
		return statisticReports;
	}

	
	public static long getTime(){
		return System.nanoTime();
	}
	
	public static void sleep(long millis){
		try {	
			Thread.sleep(millis);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
